package com.reefe.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.reefe.config.redis.RedisUtil;
import com.reefe.dto.ContentDto;
import com.reefe.dto.DtoUtil;
import com.reefe.exception.AppException;
import com.reefe.mapper.TbContentCategoryMapper;
import com.reefe.mapper.TbContentMapper;
import com.reefe.pojo.TbContent;
import com.reefe.pojo.TbContentCategory;
import com.reefe.pojo.TbContentExample;
import com.reefe.redis.JedisClient;
import com.reefe.service.ContentService;
import com.reefe.utils.FastJsonConvert;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * Created by xiao on 2018-03-07.
 */
@Component
@Service(version = "1.0.0",timeout = 30000 )
public class ContentServiceImpl implements ContentService {
    private Logger logger = Logger.getLogger(ContentServiceImpl.class);

    @Autowired
    private JedisClient jedisClient;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private TbContentMapper contentMapper;
    @Autowired
    private TbContentCategoryMapper contentCategoryMapper;
    @Value("${INDEX_CONTENT}")
    private String INDEX_CONTENT;

    @Override
    public Map<String, Object> getContentListByCid(Long cid) {
        Map<String, Object> result = new HashMap();
        //首先查询缓存，如果缓存中存在的话，就直接将结果返回给前台展示，
        //查询缓存不能影响业务流程
       /* try {
            List<ContentDto> list = ( List<ContentDto>)redisUtil.get(INDEX_CONTENT+cid);
            //如果从缓存中查到了结果
            if(list != null && !list.isEmpty()){
                result.put("data",list);
                return result;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }*/
        //查询缓存
        try{
            //有缓存则读取
            String json = jedisClient.hget(INDEX_CONTENT,cid+"");
            if(json!=null){
                List<ContentDto> list = FastJsonConvert.convertJSONToObject(json, List.class);
                result.put("data",list);
                return result;
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        List<ContentDto> list = new ArrayList<>();

        TbContentExample example = new TbContentExample();
        TbContentExample.Criteria criteria = example.createCriteria();
        //条件查询
        criteria.andCategoryIdEqualTo(cid);
        List<TbContent> listTbContent = contentMapper.selectByExample(example);

        TbContentCategory tbContentCategory = contentCategoryMapper.selectByPrimaryKey(cid);

        for(int i=0;i<listTbContent.size();i++){
            ContentDto contentDto = DtoUtil.TbContent2ContentDto(listTbContent.get(i));
            contentDto.setCategory(tbContentCategory.getName());
            list.add(contentDto);
        }
        //添加缓存，不能影响业务流程
    /*    try {
            redisUtil.set(INDEX_CONTENT+":"+cid, list);
        } catch (Exception e) {
            e.printStackTrace();
        }*/
        try {
            jedisClient.hset(INDEX_CONTENT,cid+"", FastJsonConvert.convertObjectToJSON(list));
            //设置过期时间
//          jedisClient.expire();
            jedisClient.expire(cid+"",6*1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
        result.put("data",list);
        return result;
    }

    @Override
    public int deleteContent(Long id) {
        TbContent old = getContentById(id);
        /*
            先删除缓存，再执行数据库写操作。
            删除操作成功，执行数据库操作失败，下次执行读操作Cache只会未命中一次，去数据库查询。
            若先执行写操作，再删除缓存
            写操作成功，删除缓存失败，下次执行读操作读取Cache中的脏数据，出现数据不一致。
        *
        */
        deleteHomeRedis(old.getCategoryId());
        if(contentMapper.deleteByPrimaryKey(id)!=1){
            throw new AppException("删除内容失败");
        }
        return 1;
    }
    @Override
    public int addContent(TbContent tbContent) {
        //同步缓存
        deleteHomeRedis(tbContent.getCategoryId());
        tbContent.setCreated(new Date());
        tbContent.setUpdated(new Date());
        if(contentMapper.insert(tbContent)!=1){
            throw new AppException("添加内容失败");
        }
        return 1;
    }
    @Override
    public int updateContent(TbContent tbContent) {

        TbContent old = getContentById(tbContent.getId());
        //同步缓存
        deleteHomeRedis(old.getCategoryId());
        if(tbContent.getImage().isEmpty()){
            tbContent.setImage(old.getImage());
        }
        tbContent.setCreated(old.getCreated());
        tbContent.setUpdated(new Date());
        if(contentMapper.updateByPrimaryKey(tbContent)!=1){
            throw new AppException("更新内容失败");
        }

        return 1;
    }

    @Override
    public TbContent getContentById(Long id) {
        TbContent tbContent=contentMapper.selectByPrimaryKey(id);
        if(tbContent==null){
            throw new AppException("通过id获取内容失败");
        }
        return tbContent;
    }

    //同步首页缓存
    public void deleteHomeRedis(long id){
        try {
//            redisUtil.remove(key);
            jedisClient.hdel(INDEX_CONTENT,id+"");
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
